"use strict";
//  Components.utils.import("resource://gre/modules/XPCOMUtils.jsm")
//  customizeURL = "chrome://global/content/customizeToolbar.xul";

if("undefined" == typeof(disallowScriptBtn))
{
    var disallowScriptBtn = { version: "0.3.3" }
}
else
    if(!disallowScriptBtn) disallowScriptBtn = { version: "0.3.3" };

disallowScriptBtn.prefs = {
                "extensions.disallowscriptbtn.allowPlugins" : "disallowPlugins",
                "extensions.disallowscriptbtn.bind2reload"  : "returner",
                "extensions.disallowscriptbtn.propagation2background" : "propagation" }

disallowScriptBtn.prefAppendix = "toolbar.customization.usesheet";
disallowScriptBtn.cfg   = {}    //  "chrome://disallowscriptbtn/content/modules/cfgbtntool.jsm"
disallowScriptBtn.dlg   = null; //  dlg or since 29, inline style below
disallowScriptBtn.style = null; //  style for urlbar btns gallery
disallowScriptBtn.btnReload = null; //  save extra reload btn
disallowScriptBtn.btnStop   = null; 
disallowScriptBtn.contextClass = [ "customize-context-removeFromToolbar",
                            "customize-context-removeFromPanel",
                            "customize-context-moveToPanel",
                            "customize-context-moveToToolbar" ]

disallowScriptBtn.strCustomizing = '<?xml version="1.0"?>' +
 '<window xmlns:html="http://www.w3.org/1999/xhtml" ' +
    'xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">' +
    '<html:style type="text/css" xmlns:html="http://www.w3.org/1999/xhtml">' +
       '#customization-container toolbarbutton#disallowscriptbtn-key-dot, ' +
       '#CustomizeToolbarWindow toolbarbutton#disallowscriptbtn-key-dot {' +
       ' list-style-image: url("chrome://disallowscriptbtn/skin/mandm.png"); ' +
       ' -moz-image-region: rect(0px 24px 24px 0px); }' +
       '#customization-container toolbarbutton#disallowscriptbtn-plugin-widget, ' +
       '#CustomizeToolbarWindow toolbarbutton#disallowscriptbtn-plugin-widget {' +
       ' list-style-image: url("chrome://disallowscriptbtn/skin/mode.png"); ' +
       ' -moz-image-region: rect(0px 24px 24px 0px); }' +
    ' </html:style> </window>';
    //  [customizing] #urlbar
disallowScriptBtn.strGallery = '<?xml version="1.0"?>' +
 '<window xmlns:html="http://www.w3.org/1999/xhtml" ' +
    'xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">' +
    '<html:style type="text/css" xmlns:html="http://www.w3.org/1999/xhtml">' +
    '#urlbar toolbarbutton.chromeclass-toolbar-additional' +
    ' { visibility: visible !important; }' +
    ' </html:style> </window>';

disallowScriptBtn.clickBtnReload = function(abtn, anevt)
{
    abtn.disabled = false;
    abtn.onclick = function(event) { checkForMiddleClick(this, event) };
    checkForMiddleClick(abtn, anevt);
}

disallowScriptBtn.showMenu = function(acontainer)
{
    let thevalue = document.getElementById("disallowscriptbtn-quasi-cmd").getAttribute("checked");

    for each (let [ index, themenu ] in Iterator(acontainer.children))
        if(themenu.value === thevalue) themenu.setAttribute("checked", "true")
            else themenu.removeAttribute("checked");
}

disallowScriptBtn.doDblclick = function(anode)
{
    const thevalue = { "false": true, "true": false }
    disallowScriptBtn.doMenu(thevalue[anode.getAttribute("checked")]);
},

disallowScriptBtn.doMenu = function(avalue)
{
    const thevalue = { "false": false, "true": true }
    if(gBrowser)
    {
        gBrowser.selectedBrowser.docShell.allowPlugins = thevalue[avalue.toString()];
        window.setTimeout( function(abrowser)
            {
                disallowScriptBtn.updater.doCmd(abrowser)
            }, 1, gBrowser.selectedBrowser);
    }
}

disallowScriptBtn.doSelector = function(abrowser)
{
    function computeMargin(amargin, adeflen)
    {
        let margin = amargin || "0";
        let thelen = parseInt(margin) || parseInt(0);
            margin = margin.replace(thelen.toString(), '') || "px";
        if (!(thelen >> 1) && margin.endsWith("px"))
        {
            margin = (adeflen || "").trim();
            thelen = parseInt(adeflen || 0) || parseInt(0);
            if (thelen) 
            {
                if (!(margin.endsWith(";")))
                    margin = margin.concat(";");
                return margin;
            }
            return "1em;";
        }
        return null; // nothing corrects
    }

    let thedoc = abrowser.contentDocument || { "loadOverlay": true };
    if (thedoc.loadOverlay) return; // xul document

    let selection = abrowser.contentWindow.getSelection() || {},
        focusNode = selection.focusNode || {},
        thebody = thedoc.body || thedoc.document.documentElement;
    
    let thenode = focusNode.parentNode;
    if (selection.rangeCount)
    {
        thenode = selection.getRangeAt(0).commonAncestorContainer;
        if (thenode === focusNode) thenode = focusNode.parentNode;
    }
    if (!thenode || !thebody || (thenode === thebody)) 
        return; //  already root or misunderstand

    let anchor = thenode;    //  upstairs to finds child of body
    while (!(thenode.parentNode === thebody)) 
    {
        focusNode = thenode, thenode = thenode.parentNode;
        if (!thenode) return; // fatal hole
    }

    if (focusNode.tagName) // not text node
    {
        //  below operation
        let newbody = thebody.cloneNode(false);
        let child = thenode.firstChild;
        while (child) {
            if (child.tagName) newbody.appendChild(child);
                else thenode.removeChild(child);
            child = thenode.firstChild;
        }
        thebody.parentNode.replaceChild(newbody, thebody);

        let thewin = thedoc.defaultView;
        thewin.setTimeout( function(awin) // restore selection
            {
                let selection = awin.getSelection();
                if ((newbody === anchor) || (newbody === anchor.parentNode))
                        selection.removeAllRanges();
                    else selection.selectAllChildren(anchor);
            }, 0, thewin );
        let margin = computeMargin( thewin.getComputedStyle(newbody).marginLeft, 
                      thewin.getDefaultComputedStyle(newbody).marginLeft );
        if (margin) margin = "margin-left: ".concat(margin);
        let appendix = computeMargin( thewin.getComputedStyle(newbody).marginRight, 
                      thewin.getDefaultComputedStyle(newbody).marginRight );
        if (appendix) 
        {
            appendix = "margin-right: ".concat(appendix);
            if (margin) margin = [ margin, appendix ].join(" ");
                else margin = appendix;
        }
        if (margin) newbody.style.cssText = margin;        
    }
    return;
}   //  disallowScriptBtn.doSelector = function(abrowser)

disallowScriptBtn.doCmd = function(abrowser)
{
    try {   //  stop web surfing
        abrowser.webNavigation.stop(Components.interfaces.nsIWebNavigation.STOP_CONTENT);
        if(abrowser.docShell.canExecuteScripts)
            window.setTimeout( function(abrowser)
                {
                    disallowScriptBtn.updater.doCmd(abrowser)
                }, 1, gBrowser.selectedBrowser);
        abrowser.docShell.allowJavascript = false;
    }
    catch (e) {
        Components.utils.reportError(e)
    }
}

disallowScriptBtn.returner =
{ //  F5 -> (docShell.allowJavascript = true)

    preference  : "extensions.disallowscriptbtn.bind2reload",
    cmdIsbn     : "disallowscriptbtn-material-cmd",
    cmdView     : "toolbar #disallowscriptbtn-key-dot",
    cmdRefresh  : [ "Browser:Reload", "Browser:ReloadOrDuplicate", "Browser:ReloadSkipCache" ],
    toolbar     : null,
    _activate   : false,

    startup : function()
    {
        let theflow = false;    // "disallowscriptbtn-key-dot");
        let thebtn = document.querySelector(this.cmdView);
        if(thebtn)
        {
            this.toolbar = thebtn.parentNode;
            theflow = !(thebtn.hidden);
        }
            else this.toolbar = null;

        if(disallowScriptBtn.isXulLoaded())
            this.reset(theflow);
    },

    reset : function(adirect)
    {
        if(adirect)
        {
            let theval = Services.prefs.getBoolPref(this.preference);
            let expanded = (this.toolbar) && !(this.toolbar.collapsed);
    //  dump("_dvk_dbg_, toolbar:\t"); dump(this.toolbar.localName);dump("\n\t");
    //  dump("this.toolbar.expanded:\t"); dump(expanded); dump("\n\n");
            if(theval && expanded)
            {
                document.getElementById(this.cmdIsbn).addEventListener("command", this, false);
                this.cmdRefresh.forEach(
        function(asbn) { document.getElementById(asbn).addEventListener("command", this, false) },
                this )
                this._activate = true;
                return;
            }
        }

        this.cmdRefresh.forEach(
    function(asbn) { document.getElementById(asbn).removeEventListener("command", this, false) },
            this );
        this._activate = false;

        let thebtn = document.getElementById(this.cmdIsbn);
        if(thebtn) thebtn.removeEventListener("command", this, false);
        return;
    },

    handleEvent : function(anevt)
    {
    //        alert(anevt.target.id);
        if(anevt.target.id == this.cmdIsbn)
        {
            if(!(this._activate)) this.reset(true);
        }
        else
        if(gBrowser)
        if(!(gBrowser.selectedBrowser.docShell.canExecuteScripts))
            if(document.querySelector(this.cmdView))
            {
                gBrowser.selectedBrowser.docShell.allowJavascript = true;
                window.setTimeout( function(abrowser)
                    {
                        disallowScriptBtn.updater.doCmd(abrowser)
                    }, 1, gBrowser.selectedBrowser);
            }
            else this.reset(false);
    }

}  //  returner

disallowScriptBtn.toggle =
{
    counter : 0,
    btn     : null,

    reset   : function(abtn)
    {
    //      dump("_dvk_dbg_, reset toggle:\t"); dump(this.counter); dump("\n\n");
        if(!abtn) abtn = this.btn;
        if(abtn) abtn.removeEventListener("dblclick", this, false);

        if(this.btn)
        {
            this.btn = null;
            disallowScriptBtn.updater.doCmd(gBrowser.selectedBrowser);
    //              { anode.setAttribute("command", "disallowScriptBtn-material-cmd") },
        }
    },

    startup : function(abtn)
    {
        let thecounter = ++this.counter;
        let thebtn = document.querySelector("#PanelUI-popup #disallowscriptbtn-key-dot");
        if (thebtn) return;

        window.setTimeout( function(acounter, aself)
            {
                if(aself.counter == acounter) aself.reset(null);
            }, 222, thecounter, this);

        if(!(this.btn))
        {
            this.btn = abtn;
            if(!(gBrowser.selectedBrowser.docShell.canExecuteScripts))
                abtn.addEventListener("dblclick", disallowScriptBtn.toggle, false);
        }
        return;
    },

    handleEvent : function(anevt)
    {        
        anevt.currentTarget.removeEventListener(anevt.type, this, false);
        gBrowser.selectedBrowser.docShell.allowJavascript = true;
    },
}   //  toggle subsystem

disallowScriptBtn.panelmultiview = {
    panel : null,
    reset : function(astate)
    {
        if (astate) {
            this.panel = document.getElementById("PanelUI-popup");
            if (this.panel) this.panel.addEventListener("popupshowing", this, false);
            return;
        }
        
        if (this.panel)
        {
            this.panel.removeEventListener("popupshowing", this, false);
            this.panel.removeEventListener("popuphiding", this, false);
        }

        this.panel = null;
        return;
    },

    handleEvent : function(anevt)
    {
        if (!(anevt.target === anevt.currentTarget)) return;
        let thebtn = anevt.target.querySelector("#disallowscriptbtn-key-dot");
        if (thebtn) 
        if ((anevt.type || "").indexOf("popupshow") == 0)
        {
            this.panel.addEventListener("popuphiding", this, false);
            disallowScriptBtn.updater.showPanel(thebtn);
            return;
        }
        else
            disallowScriptBtn.updater.doCmd(gBrowser.selectedBrowser);

        this.panel.removeEventListener("popuphiding", this, false);
        return;
    },
    
    update : function(abrowser)
    {
        if (abrowser && this.panel) {
            this.panel.removeEventListener("popuphiding", this, false);
            disallowScriptBtn.updater.doCmd(abrowser);
        }
    }
}

disallowScriptBtn.updater = {

    counter : 0,
    browser : null,
    front   : "Disallow javascript on current tab.",
    disabled: "The button is bidirectional by double click.",
    shadow  : "Here indicates only.",

    startup : function(adelay, abrowser)
    {
        if(abrowser) this.browser = abrowser;
        this.browser.tabContainer.addEventListener("TabSelect", this, false);
        this.browser.addEventListener("DOMContentLoaded", this, false);
        this.browser.addEventListener("pageshow", this, false);
        let thewin = this.browser.ownerDocument.defaultView;
    //  if(thewin === Services.ww.activeWindow) dump("There is activeWindow\n")
        thewin.setTimeout( function(abro) { disallowScriptBtn.updater.doCmd(abro); },
                            adelay, this.browser.selectedBrowser);
        let themodule = { };
        Components.utils.import("chrome://disallowscriptbtn/locale/utility.jsm", themodule);
        if (themodule.tooltiptxt)
        {
            this.front  = themodule.tooltiptxt.front;
            this.disabled = themodule.tooltiptxt.disabled;
            this.shadow = themodule.tooltiptxt.shadow;
        }
    },

    stop : function()
    {
        this.browser.removeEventListener("DOMContentLoaded", this, false);
        this.browser.removeEventListener("pageshow", this, false);
        this.browser.tabContainer.removeEventListener("TabSelect", this, false);
    },

    //  "DOMContentLoaded", "pageshow", "TabSelect"
    handleEvent : function(anevt)
    {
        let thecounter = ++this.counter;
        let selbro = this.browser.selectedBrowser.contentDocument;
        if (anevt.type == "TabSelect") selbro = anevt.target;
        if (anevt.target === selbro)
            window.setTimeout( function(acounter, aself)
            {
                if(aself.counter == acounter)
                    aself.doCmd(gBrowser.selectedBrowser);
            }, 555, thecounter, this);
    },

    showPanel : function(abtn)
    {
        try {
            let theval = gBrowser.selectedBrowser.docShell.canExecuteScripts;
            let thecmd = document.getElementById("disallowscriptbtn-material-cmd");
            if (theval) thecmd.removeAttribute("disabled");
                else thecmd.setAttribute( "disabled", "true" );
    //              thecmd.setAttribute("disabled", (theval) ? "false" : "true" );
            thecmd.tooltipText = (theval) ? this.front : this.shadow;
        }
        catch (e) {
            Components.utils.reportError(e)
        }
    },

    doCmd: function(aselbrowser) // charge above
    {
        if(aselbrowser)
        try {
            let theval = aselbrowser.docShell.canExecuteScripts;
            let thecmd = document.getElementById("disallowscriptbtn-material-cmd");
            if (theval) thecmd.removeAttribute("disabled");
                else thecmd.setAttribute( "disabled", "true" );
    //              thecmd.setAttribute("disabled", (theval) ? "false" : "true" );
            let thebtn = document.getElementById("disallowscriptbtn-key-dot");
            if (thebtn) thecmd.tooltipText = (theval) ? this.front : this.disabled;

            theval = (aselbrowser.docShell.allowPlugins) ? "true" : "false";
            document.getElementById("disallowscriptbtn-quasi-cmd").setAttribute("checked", theval);
    //          let thebtn = document.getElementById("plugin-mode-widget");
    //          if(thebtn) thebtn.checked = aselbrowser.docShell.allowPlugins;
        }
        catch (e) {
            Components.utils.reportError(e)
        }
    },
}  //  updater

disallowScriptBtn.disallowPlugins =
{
    preference : "extensions.disallowscriptbtn.allowPlugins",

    reset : function(avalue)
    {
        let theval = Services.prefs.getIntPref(this.preference);
            if(!(theval >> 1) && avalue)
                gBrowser.tabContainer.addEventListener("TabOpen", this, false)
            else
                gBrowser.tabContainer.removeEventListener("TabOpen", this, false);
    },

    handleEvent : function(anevt)
    {
        let thebrowser = gBrowser.getBrowserForTab(anevt.target);
        if(thebrowser) thebrowser.docShell.allowPlugins = false;
    }
}

disallowScriptBtn.propagation =
{
    preference  : "extensions.disallowscriptbtn.propagation2background",
    cmdView     : "toolbar #disallowscriptbtn-key-dot",
    toolbar     : null,

    startup : function()
    {
        let theflow = false;    //  disallowScriptBtn.propagation.
        let thebtn = document.querySelector(this.cmdView);
        if(thebtn) {
                this.toolbar = thebtn.parentNode;
                theflow = !(thebtn.hidden);
        }
            else this.toolbar = null;

        if(disallowScriptBtn.isXulLoaded())
            this.reset(theflow);
    },
    
    reset : function(adirect)
    {
        if(adirect)
        {
            let theval = Services.prefs.getBoolPref(this.preference);
            let expanded = (this.toolbar) && !(this.toolbar.collapsed);
            if(theval && expanded)
            {
                gBrowser.tabContainer.addEventListener("TabOpen", this, false);
                return;
            }
        }
        gBrowser.tabContainer.removeEventListener("TabOpen", this, false);
        return;
    },

    handleEvent : function(anevt)
    {
        if(gBrowser)
        window.setTimeout( function(atab)
            {
                if(!(gBrowser.selectedTab === atab))
                if(!(gBrowser.selectedBrowser.docShell.allowJavascript))
                {
                    let thebrowser = gBrowser.getBrowserForTab(atab);
                    if(thebrowser) thebrowser.docShell.allowJavascript = false;
                }
            }, 1, anevt.target);
    }
}   //  disallowScriptBtn.propagation

disallowScriptBtn.frameContentLoaded = function(adoc)
{
    //  "chrome://global/content/customizeToolbar.xul"
    let thewin = adoc.defaultView;
    if(thewin && (adoc.documentURIObject))
    if(!(thewin === thewin.top))    //  if frame
    try {
    //  dump("_dvk_dbg_, frameContentLoaded:\t"); dump(this.cfg.pathCustomizeDlg); dump("\n");
        let thepath = adoc.documentURIObject.path || "";
        if(thepath.indexOf(this.cfg.pathCustomizeDlg) === 0)
        {
            this.loadStrStyle(adoc, this.strCustomizing);
            this.dlg = thewin;  //  for analyzing by "aftercustomization"
        }
    }
    catch(err)
    {
        Components.utils.reportError(err)
    }
}

disallowScriptBtn.loadStrStyle = function(adoc, astyle)
{
        adoc = adoc.documentElement;
    let parser = new window.DOMParser();
    let thedoc = parser.parseFromString(astyle, "application/xml");
    if (thedoc && adoc)
    if (thedoc.documentElement)
    {
        let thestyle = thedoc.documentElement.firstElementChild;
        return adoc.insertBefore(thestyle, adoc.firstChild);
    }
    return null;
}

disallowScriptBtn.btns2navbar = function(anobj, adoc)
{
    let thestr = [ "toolbar#", " #extra-reload-button" ].join(anobj.AREA_NAVBAR);
    let thebtn = adoc.documentElement.querySelector(thestr);
    if (!thebtn) {
        anobj.addWidgetToArea("extra-reload-button", anobj.AREA_NAVBAR);
        thebtn = adoc.getElementById("extra-reload-button");
    }
    if (thebtn) thebtn.disabled = false;
    
    thestr = [ "toolbar#", " #extra-stop-button" ].join(anobj.AREA_NAVBAR);
    thebtn = adoc.documentElement.querySelector(thestr);
    if (!thebtn) anobj.addWidgetToArea("extra-stop-button", anobj.AREA_NAVBAR);    
}

disallowScriptBtn.saveBtns = function(apalette)
{
    let thebtn = apalette.querySelector("toolbarbutton#extra-reload-button");
        if (!(this.btnReload) && thebtn)
        if (!(document.getElementById("extra-reload-button")))
            this.btnReload = apalette.removeChild(thebtn);

    thebtn = apalette.querySelector("toolbarbutton#extra-stop-button");
        if (!(this.btnStop) && thebtn)
        if (!(document.getElementById("extra-stop-button")))
            this.btnStop = apalette.removeChild(thebtn);
}

disallowScriptBtn.restoreBtns = function(awin)
{
    if (!(awin.gNavToolbox)) return;

    let thebtn = this.btnReload;
    if (thebtn)
    {
        this.btnReload = null;
        awin.gNavToolbox.palette.appendChild(thebtn);
    }

        thebtn = this.btnStop;
    if (thebtn)
    {
        this.btnStop = null;
        awin.gNavToolbox.palette.appendChild(thebtn);
    }
    return;
}

disallowScriptBtn.handleEvent = function(anevt)
{
    switch(anevt.type)
    {
    case "unload" : 
        anevt.currentTarget.removeEventListener(anevt.type, this, false);
            this.shutdown();
            this.dlg = null;
    break;

    case "beforecustomization" :    //  dump("\n_dvk_dbg_, beforecustomization.\n");
        this.dlg = null;
        let thewin = Services.ww.getWindowByName(this.cfg.nameCustomizeDlg, null);
        if ((thewin) && (thewin.document))
        {
            this.loadStrStyle(thewin.document, this.strCustomizing);
        }
        else // firefox: 29
        if (window.gCustomizeMode)
            this.dlg = this.loadStrStyle(document, this.strCustomizing);

        this.saveBtns(gNavToolbox.palette);
    break;

    case "command" :
        if (document.popupNode)
        if (document.popupNode.id == "disallowscriptbtn-key-dot")
        {
            let thelist = anevt.currentTarget.classList;
            if (thelist.contains("customize-context-removeFromToolbar")
                || thelist.contains("customize-context-removeFromPanel"))
            {
                this.returner.reset(false);
                this.propagation.reset(false);
            }
            else {
            window.setTimeout(function() { disallowScriptBtn.returner.startup() }, 10);
            window.setTimeout(function() { disallowScriptBtn.propagation.startup() }, 10);
            }
        }
    break;

    case "aftercustomization" : //  anevt.target is toolbox
        window.setTimeout(function() { disallowScriptBtn.returner.startup() }, 1);
        window.setTimeout(function() { disallowScriptBtn.propagation.startup() }, 1);
        if (window.gCustomizeMode && this.dlg) // firefox: 29
        {
            document.documentElement.removeChild(this.dlg);
        let thebtn = document.getElementById("extra-reload-button");
            if (thebtn) thebtn.disabled = false;
        }
        this.dlg = null;
    break;

    case "activate" :
        window.setTimeout(function() { disallowScriptBtn.returner.startup() }, 1);
        window.setTimeout(function() { disallowScriptBtn.propagation.startup() }, 1);
        disallowScriptBtn.panelmultiview.update(gBrowser.selectedBrowser);
    break;

    case "DOMContentLoaded" :
        this.frameContentLoaded(anevt.target);
    break;

    case "toolbarvisibilitychange" :
        window.setTimeout( function() {
            if(disallowScriptBtn.isXulLoaded())
                disallowScriptBtn.propagation.reset(true)
        }, 1);
        window.setTimeout( function() {
            if(disallowScriptBtn.isXulLoaded())
                disallowScriptBtn.returner.reset(true)
        }, 1);        
    break;
    }
}

disallowScriptBtn.mutate = new MutationObserver(
    function(amutations)
    {
        let removed = amutations.some( function(aclause) {
            return (aclause.removedNodes) ? true : false ;
            }); // NOTE: does it need ?
        //turn (aclause.addedNodes) ? true : false ;
        if (!removed) return; // && (!added)

        let thepalette = gNavToolbox.palette;
        if (!thepalette) return;

        disallowScriptBtn.mutate.disconnect();
        window.setTimeout(function() { disallowScriptBtn.returner.startup() }, 2);
        window.setTimeout(function() { disallowScriptBtn.propagation.startup() }, 2);
        disallowScriptBtn.mutate = null;
        return;
}); //  new MutationObserver(

disallowScriptBtn.observe = function(asubject, atopic, adata)
{    
    if(atopic == "nsPref:changed")
    if(this.prefs[adata])
    {
        let thattr = this.prefs[adata];
        this[thattr].reset(true);
    }
    else    //  this.prefAppendix
    if(Services.prefs.getBoolPref(this.prefAppendix))
    {
        window.removeEventListener("beforecustomization", this, false);
        window.addEventListener("DOMContentLoaded", this, false);
    }
    else {
        window.removeEventListener("DOMContentLoaded", this, false);
        window.addEventListener("beforecustomization", this, false);
    }
}

disallowScriptBtn.isXulLoaded = function()
{
    if(document.getElementById("disallowscriptbtn-container"))
        return true;
    return false;
}

/* starter phase,
 * 
 *  some.addEventListener
 *
 *  if(disallowScriptBtn.upgrade) then display();
 *  else :
 *  
 *      init: gNavToolbox.palette
 *
 *      if(gNavToolbox.palette)
 *          if(less then "0.1.7") exchange between new 2 old btn
 *          else
 *              run firstLaunch subsystem
 */
disallowScriptBtn.startup = function()
{
Components.utils.import("chrome://disallowscriptbtn/content/modules/cfgbtntool.jsm", this.cfg);
//dump("_dvk_dbg_, disallowScriptBtn startup:\t"); dump(gNavToolbox); dump("\n");
//    var theAppButtonDisplay = this.onceUpdateAppButtonDisplay;
//    Services.obs.addObserver(this, "browser-delayed-startup-finished", false);

    //  initialize update sub system
    this.updater.startup(10, gBrowser);
    let apalette = null;
    if (gNavToolbox)
    {
        this.mutate.observe( gNavToolbox, { childList: true, subtree: true } );
        gNavToolbox.addEventListener( "toolbarvisibilitychange", this, false );
        apalette = gNavToolbox.palette;
    }

    this.contextClass.forEach( function(asuffix) {
            let thestr = [ "menupopup > menuitem", asuffix ].join(".");
            let thecmd = this.querySelector(thestr);
            if (thecmd) thecmd.addEventListener("command", disallowScriptBtn, false);
        }, document.documentElement );

    //  Behaviour of New Tab (Window) for allowPlugins attr
    this.disallowPlugins.reset(true);
    this.panelmultiview.reset(true);

    for (let thekey in this.prefs)
        Services.prefs.addObserver(thekey, this, false);
    if (!(window.gCustomizeMode)) Services.prefs.addObserver(this.prefAppendix, this, false);
    
//    window.updateAppButtonDisplay = theAppButtonDisplay;
    if (window.gCustomizeMode)
        window.addEventListener("beforecustomization", this, false);
    else
    if(Services.prefs.getBoolPref(this.prefAppendix))
        window.addEventListener("DOMContentLoaded", this, false)
    else
        window.addEventListener("beforecustomization", this, false);
    window.addEventListener("aftercustomization", this, false);
    window.setTimeout( function() {
        window.addEventListener("activate", disallowScriptBtn, false) }, 111 );

    let theforce = Services.prefs.getBoolPref("extensions.disallowscriptbtn.firstLaunch");
    if (apalette) //      this.cfg.loadBtns(window);
    try {
        if (theforce) this.cfg.insertBtns(window);
    //      { apalette.insertBtns(window) }, 1, this.cfg );
    //      this.version = LAST_VERSION;  due extra btns are not restoring
        if (document.documentElement.hasAttribute("customizing"))
        {
    //like: sallowScriptBtn.saveBtns = function(apalette)
        let thebtn = apalette.querySelector("toolbarbutton#extra-reload-button");
            if (thebtn) apalette.removeChild(thebtn);

        thebtn = apalette.querySelector("toolbarbutton#extra-stop-button");
            if (thebtn) apalette.removeChild(thebtn);
        }
    }
    catch (err)
    {
        Components.utils.reportError(err)
    }
}   // disallowScriptBtn.startup = function(anupgrade)

disallowScriptBtn.sleep = function()    //  ADDON_DISABLE or ADDON_UPGRADE
{
    this.shutdown(); // this.cfg = null;
 const allkingsmen = [ "activate", "aftercustomization", "beforecustomization", "DOMContentLoaded", "unload" ]
    try {
        allkingsmen.forEach(
            function(atype) { window.removeEventListener(atype, this, false) },
                this);

        gNavToolbox.removeEventListener("toolbarvisibilitychange", this, false);

        this.contextClass.forEach( function(asuffix) {
            let thestr = [ "menupopup > menuitem", asuffix ].join(".");
            let thecmd = this.querySelector(thestr);
            if (thecmd) thecmd.removeEventListener("command", disallowScriptBtn, false);
        }, document.documentElement );
    
    }
    catch (err)
    {
        Components.utils.reportError(err)
    }

    try {
        this.disallowPlugins.reset(false);
        this.panelmultiview.reset(false);
        this.updater.stop();
        this.returner.reset(false);
        this.propagation.reset(false);

        if (this.dlg)
        if (gNavToolbox.customizing)
        {  //  if frame, until firefox 29
            this.dlg.finishToolbarCustomization();
            if(Services.prefs.getBoolPref(this.prefAppendix))
                window.setTimeout(
                    function() { window.BrowserCustomizeToolbar()
                    }, 0);
        }
        else    // suppose firefox 29 and next
            document.documentElement.removeChild(this.dlg);
    }
    catch (err)
    {
        Components.utils.reportError(err)
    }
    finally{ this.dlg = null }
}

disallowScriptBtn.shutdown = function()    //  can be bool
{
    if (this.mutate) this.mutate.disconnect();
    //  dump("_dvk_dbg_, disallowScriptBtn shutdown:\t"); dump(anevt); dump("\n");
    try {
        for (let thekey in this.prefs)
            Services.prefs.removeObserver(thekey, this);
        if (!(window.gCustomizeMode)) Services.prefs.removeObserver(this.prefAppendix, this);
    //      window.removeEventListener("deactivate", this, false);
    }
    catch (err)
    {
        Components.utils.reportError(err)
    }
    this.cfg = null;
}
